#include "ChatSession.h"
#include "mysql/MysqlUtils.h"

#include <ChatServer.h>
#include <boost/smart_ptr/make_shared_array.hpp>
#include <string>
#include <system/System.h>


ChatServer* ChatServer::app = nullptr;

ChatServer::ChatServer(const tcp::endpoint& endpiont)
    : ioc{},
      acceptor(ioc, endpiont),
      ssl_ctx(boost::asio::ssl::context::tls_client),
      mysqlconn(ioc.get_executor(), ssl_ctx) {
    app = this;
    initConfig();
    // 初始化 MySQL 数据库连接
    initMysql();
    initHttpServer();
    m_sessionManager = boost::make_shared<ChatSessionManager>();
    m_roomManager    = boost::make_shared<ChatRoomManager>();
}

ChatServer::~ChatServer() {
}

ChatServer& ChatServer::getInstance() {
    if (app) {
        return *app;
    }

    using namespace std;

    Config config;
    config.loadConfig("./config/config.json");
    std::cout << boost::json::value_from(config) << std::endl;

    boost::asio::io_context ioc;
    tcp::endpoint endpoint(tcp::v4(), config.listenport);

    app = new ChatServer(endpoint);

    return *app;
}

bool ChatServer::initConfig() {
    return config.loadConfig("./config/config.json");
}

void ChatServer::initMysql() {
    MysqlUtils::connect();
}

net::io_context& ChatServer::io_context() {
    return getInstance().ioc;
}

void ChatServer::initConnect() {
}

void ChatServer::initHttpServer() {
    http_server = boost::make_shared<ChatHttpServer>(ioc, config.httpserver.port, config.httpserver.doc_root);
}

void ChatServer::exec() {
    doAccept();
    ioc.run();
}

boost::mysql::tcp_ssl_connection& ChatServer::mysqlConnection() {
    // TODO: 在此处插入 return 语句
    return mysqlconn;
}

ChatSessionManager& ChatServer::sessionManager() {
    // TODO: 在此处插入 return 语句
    return *m_sessionManager;
}

ChatRoomManager& ChatServer::roomManager() {
    // TODO: 在此处插入 return 语句
    return *m_roomManager;
}

void ChatServer::doAccept() {
    std::cout << "doAccept" << std::endl;
    acceptor.async_accept(
        [this](boost::system::error_code ec, tcp::socket socket) {
            if (ec) {
                std::cerr << "doAccept:" << ec.what() << std::endl;
                return;
            }
            newSessionHandler(socket);
            this->doAccept();
        });
}

void ChatServer::newSessionHandler(tcp::socket& socket) {
    std::cout << "new connect" << std::endl;
    auto new_session = boost::make_shared<ChatSession>(ioc, std::move(socket));
    new_session->start();
}
